﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EstimationStudio.Core;
using System.Windows.Forms.DataVisualization.Charting;

namespace EstimationStudio.UI
{
    public partial class EstimateControl : UserControl
    {
        public EstimateControl()
        {
            InitializeComponent();
        }

        public EstimateControl(IEnumerable<ProjectPhase> projectPhases)
            : this()
        {
            this.ProjectPhases = projectPhases;
        }

        public event EventHandler Changed;

        public Boolean Initialized { get; set; }

        public IEnumerable<ProjectPhase> ProjectPhases { get; protected set; }

        private void EstimateControl_Load(object sender, EventArgs e)
        {
        }

        private void btnAddFeature_Click(object sender, EventArgs e)
        {
            AddFeature(new Feature());
            Control_Changed(this, EventArgs.Empty);
        }

        private void btnDeleteFeature_Click(object sender, EventArgs e)
        {
            DeleteFeature();
            Control_Changed(this, EventArgs.Empty);
        }

        private void Control_Changed(object sender, EventArgs e)
        {
            if (Changed != null)
                Changed(this, EventArgs.Empty);

            CalculateEstimate(UnloadEstimate());
        }

        private void Initialize()
        {
            if (ProjectPhases != null)
            {
                foreach (var projectPhase in ProjectPhases)
                    cboPhase.Items.Add(projectPhase);
            }
            Initialized = true;
        }

        public void LoadEstimate(Estimate estimate)
        {
            if (!Initialized)
                Initialize();

            if (estimate == null)
                return;

            txtTitle.Text = estimate.Title;
            txtIdentifier.Text = estimate.EstimateId;
            txtProblem.Text = estimate.ProblemDescription;
            txtSolutionNotes.Text = estimate.SolutionNotes;

            dateEstimated.Value = estimate.DateEstimated;

            if (estimate.ProjectPhase != null)
                cboPhase.SelectedItem = estimate.ProjectPhase;

            FeatureContainer.Controls.Clear();
            if (estimate.Features != null)
            {
                foreach (var feature in estimate.Features.OrderByDescending(f => f.Name))
                    AddFeature(feature);
            }

            AdjustmentContainer.Controls.Clear();
            if (estimate.AdjustmentFactors != null)
            {
                foreach (var adjustmentFactor in estimate.AdjustmentFactors.OrderByDescending(a => a.Name))
                    AddAdjustmentFactor(adjustmentFactor);
            }
        }

        public Estimate UnloadEstimate()
        {
            ProjectPhase selectedProjectPhase = ProjectPhases.FirstOrDefault(p => p == cboPhase.SelectedItem);

            Estimate estimate = new Estimate
            {
                Title = txtTitle.Text,
                EstimateId = txtIdentifier.Text,
                ProblemDescription = txtProblem.Text,
                SolutionNotes = txtSolutionNotes.Text,
                DateEstimated = dateEstimated.Value,
                ProjectPhase = selectedProjectPhase,
            };

            foreach (FeatureControl featureControl in FeatureContainer.Controls)
                estimate.Features.Add(featureControl.UnloadFeature());

            foreach (AdjustmentFactorControl adjustmentFactorControl in AdjustmentContainer.Controls)
                estimate.AdjustmentFactors.Add(adjustmentFactorControl.UnloadAdjustmentFactor());

            return estimate;
        }

        private void AddFeature(Feature feature)
        {
            var featureControl = new FeatureControl()
            {
                Dock = DockStyle.Top
            };
            featureControl.Changed += Control_Changed;
            featureControl.LoadFeature(feature);
            FeatureContainer.Controls.Add(featureControl);
        }

        private void DeleteFeature()
        {
         IList<FeatureControl> controlsToDelete = new List<FeatureControl>();
         foreach (FeatureControl control in FeatureContainer.Controls)
             if (control.Selected)
                 controlsToDelete.Add(control);

         foreach (FeatureControl control in controlsToDelete)
             FeatureContainer.Controls.Remove(control);
        }

        private void AddAdjustmentFactor(AdjustmentFactor adjustmentFactor)
        {
            var adjustmentFactorControl = new AdjustmentFactorControl()
            {
                Dock = DockStyle.Top
            };
            adjustmentFactorControl.Changed += Control_Changed;
            adjustmentFactorControl.LoadAdjustmentFactor(adjustmentFactor);
            AdjustmentContainer.Controls.Add(adjustmentFactorControl);
        }

        private void CalculateEstimate(Estimate estimate)
        {
            lblBestCaseLow.Text = estimate.BestCase.Low.ToString("N2");
            lblBestCaseHigh.Text = estimate.BestCase.High.ToString("N2");
            lblNominalCaseLow.Text = estimate.ExpectedCase.Low.ToString("N2");
            lblNominalCaseHigh.Text = estimate.ExpectedCase.High.ToString("N2");
            lblWorstCaseLow.Text = estimate.WorstCase.Low.ToString("N2");
            lblWorstCaseHigh.Text = estimate.WorstCase.High.ToString("N2");
        }
    }
}